package checker

import (
    "github.com/fsnotify/fsnotify"
    "io/fs"
    "log"
    "os"
    "path/filepath"
    "strings"
    "upload-ftp/app/uploader"
)

func Run() {
    watch()
}

func send(path string, op string, size int64) {
    uploader.FileChan <- uploader.PathStruct{
        Path: path,
        Size: size,
        Op:   op,
    }
}

func watch() {
    root := os.Getenv("WORK_DIR")
    log.Println("监听当前工作目录:", root)
    filepath.Walk(root, func(path string, info fs.FileInfo, err error) error {
        //log.Println("path: ", path)
        if info.IsDir() {
            if len(path) > 1 && strings.HasPrefix(filepath.Base(path), ".") {
                return filepath.SkipDir
            }
            watchFolder(path)
        } else {
            uploader.UploadChan <- uploader.PathStruct{
                Path: path,
                Size: info.Size(),
                Op:   "Create",
            }
        }
        return err
    })
}

func watchFolder(dir string) {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatalln("Watch dir failed:", err)
    }
    go func() {
        for {
            select {
            case event, ok := <-watcher.Events:
                //log.Println("event stat err:", err, event.Op)
                if !ok {
                    return
                }
                info, err := os.Stat(event.Name)
                if err != nil {
                    //log.Println("event stat err:", err, event.Op)
                } else if info.IsDir() {
                    if (event.Op & fsnotify.Create) == fsnotify.Create {
                        watchFolder(event.Name)
                    }
                } else if ((event.Op & fsnotify.Write) == fsnotify.Write) || ((event.Op & fsnotify.Create) == fsnotify.Create) {
                    //log.Println("event and send", event.Name, event.Op)
                    send(event.Name, event.Op.String(), info.Size())
                }
            case err, ok := <-watcher.Errors:
                if !ok {
                    return
                }
                log.Println("watcher error:", err)
            }
        }
    }()
    //log.Println("Watching:", dir)
    err = watcher.Add(dir)
    if err != nil {
        log.Fatalln("Add watch failed:", err)
    }
}
